# include<stdio.h>
# include<string.h>
# include<stdlib.h>
# include<stdbool.h>
# define LIST_INIT_SIZE 100//初次估计线性表所需的空间
# define LIST_INCREAMENT 10//每次增加10个空间
typedef enum Status{
    success,fail,fatal,range_error
} Status;//success成功，fail失败，fatal致命的错误，range_error越界
typedef int ElemType;
typedef struct SqList
{
    ElemType *elem;//基地址指针
    int length;//线性表长度
    int list_size;//线性表空间大小
}SqList,*Ptr ;
typedef Ptr SqListPtr;
Status List_init(SqListPtr L);//线性表构建
Status List_Retrival(SqListPtr L,int pos,ElemType *elem);//按位查找，按照pos位置，查找值，并把它赋在elem上
Status List_Locate(SqListPtr L,ElemType elem,int *pos);//按值查找，根据elem，对照线性表，找到他所在的位置并赋给pos
Status List_insert(SqListPtr L,int pos,ElemType elem);//插入元素操作
Status List_delete(SqListPtr L,int pos);//删除pos位置的数据
void List_clear(SqListPtr L);//清空线性表
void List_Destory(SqListPtr L);//销毁线性表
void List_print(SqListPtr L);//输出
void print(Status i);
int main(){
    SqList La;
    SqListPtr L = NULL;
    L = &La;
    int n = 0;
    //生成测试
    Status i;
    printf("生成数据表\n");
    i = List_init(L);
    print(i);


    //插入测试
    printf("请输入要生成的数据元素个数\n");
    scanf("%d",&n);
    for (size_t i = 1; i < n+1; i++)
    {
        List_insert(L,i,n-i+1);
    }
    List_print(L);


    //按位查找测试
    int pos;
    ElemType elem;
    printf("请输入要按位查找的位置\n");
    scanf("%d",&pos);
    List_Retrival(L,pos,&elem);
    printf("找到的对应值是%d\n",elem);


    //按值查找测试
    printf("请输入要查找的值\n");
    scanf("%d",&elem);
    List_Locate(L,elem,&pos);
    printf("找到的对应位置是%d\n",pos);


    //删除测试
    printf("请输入要删除的位置\n");
    scanf("%d",&pos);
    i=List_delete(L,pos);
    print(i);
    List_print(L);
    

    List_Destory(L);
    
}
Status List_init(SqListPtr L){
    Status s = success;
    L->list_size = LIST_INIT_SIZE;
    L->length = 0;
    L->elem = (ElemType *)malloc(L->list_size*sizeof(ElemType));
    if (L->elem == NULL)
    {
        s = fatal;
    }
    return s;
}
Status List_Retrival(SqListPtr L,int pos,ElemType *elem){
    Status s = range_error;
    if (L)
    {
      if ((pos - 1) >= 0 && (L->length - pos+1) > 0)
      {
        *elem = L->elem[pos - 1];
        s = success;
      }
    }else{
        s = fatal;
    }
    return s;     
}
Status List_Locate(SqListPtr L,ElemType elem,int *pos){
    Status s = range_error;
    if (L)
    {
        for (size_t i = 0;  i < L->length; i++)
        {
           if (elem == L->elem[i])
           {
                *pos = i + 1;
                s = success;
                break; 
           }
        }
    }else{
        s = fatal;
    }
    return s;     
}
Status List_insert(SqListPtr L,int pos,ElemType elem){
    Status s = range_error;
    if ((pos - 1) >= 0 && (L->length - pos+1) >= 0)
    {
        if (L && (L->length < L->list_size))
        {
            for (size_t i = L->length; i > pos-2; i--)
            {
                L->elem[i+1] = L->elem[i];
            }
            L->elem[pos-1] = elem;
            L->length++;
            s = success;
        }
    }else s = fail;
    return s;
}
Status List_delete(SqListPtr L,int pos){
    Status s = range_error;
    if (L)
    {
        if ((pos - 1) >= 0 && (L->length - pos +1)>0)
        {
            for (size_t i = pos-1; i < L->length; i++)
            {
                L->elem[i] = L->elem[i+1];
            }
            L->length--;
            s = success;
        }
    }else s = fatal;
    return s;
}
void List_clear(SqListPtr L){
    L->length = 0;
}
void List_Destory(SqListPtr L){
    if (L)
    {
        free(L->elem);
    }
}
void List_print(SqListPtr L){
    for (size_t i = 0; i < L->length; i++)
    {
        printf("%d ",L->elem[i]);
    }
    printf("\n");
}
void print(Status i){
    switch (i)
    {
    case 0:
        printf("success\n");
        break;
    case 1:
        printf("fail\n");
        break;
    case 2:
        printf("fatal\n");
        break;
    case 3:
        printf("range_error\n");
        break;
    default:
        break;
    }
}
